/*
 *   项目名称：rpc-demo
 *   文件名称：com.xiaolon.rpc.server.HttpServerHandler
 *
 *   创建人：  ZHOU XIAO LONG
 *   创建日期：2024/12/3
 *
 */
package com.xiaolon.rpc.server;

import com.xiaolon.rpc.model.RpcRequest;
import com.xiaolon.rpc.model.RpcResponse;
import com.xiaolon.rpc.registry.LocalRegistry;
import com.xiaolon.rpc.serializer.JdkSerializer;
import com.xiaolon.rpc.serializer.Serializer;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;

import java.io.IOException;
import java.lang.reflect.Method;
import java.security.spec.RSAPrivateCrtKeySpec;

/*
 * 类描述：HttpServerHandler
 * Http请求处理
 */
public class HttpServerHandler implements Handler<HttpServerRequest> {
    @Override
    public void handle(HttpServerRequest request) {
        // 指定序列化器
        final Serializer serializer = new JdkSerializer();

        // 记录日志
        System.out.println("Received request: "+ request.method()+" "+ request.uri());

        // 异步处理Http请求
        request.bodyHandler(
                body->{
                    byte[] bytes = body.getBytes();
                    RpcRequest rpcRequest = null;
                    try{
                        rpcRequest = serializer.deserialize(bytes, RpcRequest.class);
                    }catch (Exception e){
                        e.printStackTrace();
                    }

                    RpcResponse rpcResponse = new RpcResponse();
                    //如果请求为null，直接返回
                    if(rpcRequest==null){
                        rpcResponse.setMessage("rpcRequest is null");
                        doResponse(request, rpcResponse, serializer);
                        return;
                    }

                    try{
                        Class<?> implClass = LocalRegistry.get(rpcRequest.getServiceName());
                        Method method = implClass.getMethod(rpcRequest.getMethodName(), rpcRequest.getParameterTypes());
                        Object result = method.invoke(implClass.newInstance(), rpcRequest.getArgs());
                        // 封装返回结果
                        rpcResponse.setData(result);
                        rpcResponse.setDataType(method.getReturnType());
                        rpcResponse.setMessage("ok");
                    }catch (Exception e){
                        e.printStackTrace();
                        rpcResponse.setMessage(e.getMessage());
                        rpcResponse.setException(e);
                    }
                    doResponse(request, rpcResponse, serializer);
                }
        );

    }


    /**
     * 响应
     * @param request
     * @param rpcResponse
     * @param serializer
     */
    void doResponse(HttpServerRequest request, RpcResponse rpcResponse, Serializer serializer){
        HttpServerResponse httpServerResponse = request.response()
                .putHeader("content-type", "application/json");
        try{
            byte[] serialized = serializer.serialize(rpcResponse);
            httpServerResponse.end(Buffer.buffer(serialized));
        }catch (IOException e){
            e.printStackTrace();
            httpServerResponse.end(Buffer.buffer());
        }

    }
}
